#!/usr/bin/perl

use strict;
use warnings;
use DBI;
use English qw(-no_match_vars);
use Getopt::Long qw(:config no_ignore_case);
use Time::Local;

sub usage {

    print <<EOF;

Usage:
   $PROGRAM_NAME args, where args are
       --vm <vm name>
       --host <compute node>
       --cycles <number of repeating periods>
       --start <YYYY:MM:DD:HH:MM:SS>
       --dispersion <variation in cpu values>
       --pairs <"pcpu1,hours1 pcpu2,hours2 .. ">
EOF
    exit 1;
}

my $args = {};

# Parse the options from the command line
GetOptions( $args, 'vm=s', 'host=s', 'cycles=i', 'start=s', 'dispersion=i',
    'pairs=s', );

for my $arg (qw(vm host cycles start dispersion pairs)) {
    usage() unless exists $args->{$arg};
}

my ( $year, $month, $day, $hour, $minute, $second ) =
  $args->{start} =~ /^(\d\d\d\d):(\d\d):(\d\d):(\d\d):(\d\d):(\d\d)$/;
usage() unless $second;

# we intentionally set seconds to zero to provide more accurate sum of VMs loads
my $start = timelocal( 0, $minute, $hour, $day, $month - 1, $year );

my $vm   = $args->{vm};
my $host = $args->{host};
my $cycles     = $args->{cycles};
my @pairs      = split /\s/, $args->{pairs};

my $dsn = "dbi:mysql:vmstats:localhost";
my $dbh = DBI->connect( $dsn, 'openstack', 'openstack' )
  or die("cannot connect to $dsn using openstack/openstack: $DBI::errstr");
my $sth =
  $dbh->prepare("insert into vmstats (vm, host, cpu, time) values(?,?,?,from_unixtime(?))")
  or die $dbh->errstr;

while ( $cycles-- ) {

    for my $pair (@pairs) {
        my $dispersion = $args->{dispersion};
        my ( $load, $hours ) = split ',', $pair;
        $dispersion = $load if $dispersion > $load;
        my $end = $start + $hours * 60 * 60;
        for ( my $t = $start ; $t < $end ; $t = $t + 60 ) {
            my $cpu = ($load + int( 2 * rand($dispersion) - $dispersion)) % 100;
            $sth->execute( $vm, $host, $cpu, $t );
        }
        $start = $end;
    }
}

$dbh->disconnect;
